package dbm

import (
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

type MgoSession struct {
	Session  *mgo.Session
	Database string
}

type IMgoSchema interface {
	CollectionName() string
	Id_() interface{}
}
type MgoSchemaBase struct {
	Id bson.ObjectId `json:"Id" bson:"_id,omitempty"` //唯一ID
}

func (db *MgoSession) Close() {
	db.Session.Close()
}

func (db *MgoSession) GetCollection(collectionName string) *mgo.Collection {
	return db.Session.DB(db.Database).C(collectionName)
}

func (db *MgoSession) Create(schema IMgoSchema) error {
	c := db.GetCollection(schema.CollectionName())
	return c.Insert(schema)
}

func (db *MgoSession) Get(selector bson.M, schema IMgoSchema) error {
	c := db.GetCollection(schema.CollectionName())
	return c.Find(selector).One(schema)
}

func (db *MgoSession) GetId(schema IMgoSchema) error {
	c := db.GetCollection(schema.CollectionName())
	return c.FindId(schema.Id_()).One(schema)
}

func (db *MgoSession) GetById(id interface{}, schema IMgoSchema) error {
	c := db.GetCollection(schema.CollectionName())
	return c.FindId(id).One(schema)
}

func (db *MgoSession) GetAll(collectionName string, selector bson.M, schemas interface{}) error {
	c := db.GetCollection(collectionName)
	return c.Find(selector).All(schemas)
}

func (db *MgoSession) Count(collectionName string, selector bson.M) (n int, err error) {
	c := db.GetCollection(collectionName)
	return c.Find(selector).Count()
}

func (db *MgoSession) Replace(selector bson.M, schema IMgoSchema) error {
	c := db.GetCollection(schema.CollectionName())
	return c.Update(selector, schema)
}

func (db *MgoSession) ReplaceId(schema IMgoSchema) error {
	c := db.GetCollection(schema.CollectionName())
	return c.UpdateId(schema.Id_(), schema)
}

func (db *MgoSession) Update(collectionName string, selector bson.M, update bson.M) error {
	c := db.GetCollection(collectionName)
	return c.Update(selector, update)
}

func (db *MgoSession) UpdateSet(collectionName string, selector bson.M, update bson.M) error {
	c := db.GetCollection(collectionName)
	return c.Update(selector, bson.M{"$set": update})
}

func (db *MgoSession) RemoveId(collectionName string, id interface{}) error {
	c := db.GetCollection(collectionName)
	return c.RemoveId(id)
}

func (db *MgoSession) Save(schema IMgoSchema, isNew bool) error {
	if isNew {
		return db.Create(schema)
	} else {
		return db.ReplaceId(schema)
	}
}

func (db *MgoSession) SaveAuto(schema IMgoSchema) error {
	_, ok := db.FindKey(schema.CollectionName(), bson.M{"_id": schema.Id_()})
	if ok {
		return db.ReplaceId(schema)
	} else {
		return db.Create(schema)
	}
}

//--------------------------------------------- 查找Key ---------------------------------------------------------------

func (db *MgoSession) FindKey(collectionName string, selector bson.M) (string, bool) {
	schema := &MgoSchemaBase{}
	c := db.GetCollection(collectionName)
	err := c.Find(selector).One(schema)
	if err == nil {
		return schema.Id.Hex(), true
	}else {
		return "", false
	}
}
